package CSDN_Blog_Util;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Objects;
import java.util.stream.Stream;

/**
 * 批量给指定目录下所有.md文件末尾追加文本工具类（Java 8 兼容版）
 * 追加内容从【当前类同级别目录】的 append.md 文件中读取
 */
public class MdFileAppender {

    // ===================== 配置成员变量（直接修改这里即可）=====================
    /** .md文件所在根目录（绝对路径） */
    private static final String ROOT_DIR_PATH = "C:\\Users\\fyakm\\Downloads\\blog"; // 示例：D:/notes 或 /Users/xxx/Documents/md
    /** 是否遍历子目录（true=包含所有子目录，false=仅当前目录） */
    private static final boolean INCLUDE_SUB_DIR = true;
    /** 存储追加内容的文件（和当前类同目录下的 append.md） */
    private static final String APPEND_FILE_NAME = "append.md"; // 固定文件名，无需修改
    // =========================================================================

    /**
     * 核心方法：给目录下.md文件追加文本
     * @param rootDirPath 根目录路径
     * @param appendText 要追加的文本（从同目录append.md读取）
     * @param includeSubDir 是否遍历子目录
     * @throws IOException 目录访问或文件读写异常
     */
    public static void appendToMdFiles(String rootDirPath, String appendText, boolean includeSubDir) throws IOException {
        // 1. 验证参数合法性
        Objects.requireNonNull(rootDirPath, "根目录路径不能为空");
        Objects.requireNonNull(appendText, "追加文本不能为空（append.md可能为空或读取失败）");
        Path rootDir = Paths.get(rootDirPath);

        // 2. 验证目录是否存在且是目录
        if (!Files.exists(rootDir)) {
            throw new IllegalArgumentException("目录不存在：" + rootDirPath);
        }
        if (!Files.isDirectory(rootDir)) {
            throw new IllegalArgumentException("不是有效目录：" + rootDirPath);
        }

        // 3. 遍历目录（深度：子目录=Integer.MAX_VALUE，仅当前=1）
        int maxDepth = includeSubDir ? Integer.MAX_VALUE : 1;
        // Java 8 支持 Files.walk()，需注意 try-with-resources 自动关闭流
        try (Stream<Path> fileStream = Files.walk(rootDir, maxDepth)) {
            fileStream
                    // 过滤：仅保留文件 + .md后缀
                    .filter(Files::isRegularFile)
                    .filter(path -> path.getFileName().toString().endsWith(".md"))
                    .forEach(path -> {
                        try {
                            // 4. 追加文本（Java 8 支持的 API，UTF-8 编码，APPEND 模式不覆盖）
                            Files.write(
                                    path,
                                    appendText.getBytes(StandardCharsets.UTF_8),
                                    StandardOpenOption.APPEND
                            );
                            System.out.println("✅ 成功追加：" + path.toAbsolutePath());
                        } catch (IOException e) {
                            // 单个文件失败不中断整体流程
                            System.err.println("❌ 失败（" + e.getMessage() + "）：" + path.toAbsolutePath());
                        }
                    });
        }

        System.out.println("\n🎉 执行完成！已处理所有符合条件的.md文件");
    }

    /**
     * 读取【当前类同级别目录】下的 append.md 文件内容（Java 8 兼容）
     * @return append.md 中的文本（含换行符）
     * @throws IOException 读取append.md失败（文件不存在、无权限等）
     * @throws URISyntaxException 目录路径解析异常
     */
    private static String readAppendContent() throws IOException, URISyntaxException {
        // 关键：动态获取当前类（MdFileAppender）的所在目录路径（Java 8 兼容）
        Class<?> clazz = MdFileAppender.class;
        URL classDirUrl = clazz.getResource(""); // 获取同级别目录的 URL
        if (classDirUrl == null) {
            throw new IOException("无法获取当前类所在目录，请检查项目结构");
        }

        // 将 URL 转成 Path 对象（Java 8 支持）
        URI classDirUri = classDirUrl.toURI();
        Path classDirPath = Paths.get(classDirUri);
        // 拼接 append.md 文件名，得到完整路径（同级别目录下）
        Path appendFilePath = classDirPath.resolve(APPEND_FILE_NAME);

        // 验证 append.md 是否存在
        if (!Files.exists(appendFilePath)) {
            throw new IOException("未找到追加内容文件：" + appendFilePath.toAbsolutePath() + "\n请在 " + classDirPath.toAbsolutePath() + " 目录下创建 append.md 并写入要追加的内容");
        }

        // 验证是否是有效文件（不是目录）
        if (!Files.isRegularFile(appendFilePath)) {
            throw new IOException("append.md 不是有效文件（可能是目录）：" + appendFilePath.toAbsolutePath());
        }

        // 读取文件内容（Java 8 兼容：用 readAllBytes() 替代 readString()）
        byte[] contentBytes = Files.readAllBytes(appendFilePath);
        String content = new String(contentBytes, StandardCharsets.UTF_8); // 手动转字符串

        // 验证内容不为空
        if (content.trim().isEmpty()) {
            throw new IOException("append.md 文件内容为空，请写入要追加的文本：" + appendFilePath.toAbsolutePath());
        }

        System.out.println("📖 成功读取 append.md 内容，路径：" + appendFilePath.toAbsolutePath() + "，长度：" + content.length() + " 字符");
        return content;
    }

    // 主方法：直接运行即可（Java 8 环境兼容）
    public static void main(String[] args) {
        try {
            // 1. 读取同级别目录下 append.md 中的追加内容（Java 8 兼容）
            String appendText = readAppendContent();
            // 2. 调用核心方法批量追加
            appendToMdFiles(ROOT_DIR_PATH, appendText, INCLUDE_SUB_DIR);
        } catch (Exception e) {
            System.err.println("❌ 程序异常终止：" + e.getMessage());
            e.printStackTrace();
        }
    }
}